/**   
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-12-06 09:51:29  
 * Copyright (c) 2015- joysuch-版权所有     
 */

package com.joysuch.wwyt.bp.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Objects;

import javax.transaction.Transactional;

import com.joysuch.wwyt.bp.bean.BpRegulationDocumentAddBean;
import com.joysuch.wwyt.bp.bean.BpRegulationDocumentEditBean;
import com.joysuch.wwyt.bp.bean.BpRegulationDocumentListBean;
import com.joysuch.wwyt.bp.bean.BpRegulationDocumentListSearchBean;
import com.joysuch.wwyt.bp.entity.BpRegulationDocument;
import com.joysuch.wwyt.bp.entity.dsl.QBpRegulationDocument;
import com.joysuch.wwyt.bp.enums.RegulationDocumentTypes;
import com.joysuch.wwyt.bp.repository.BpRegulationDocumentDao;
import com.joysuch.wwyt.bp.service.BpRegulationDocumentService;
import com.joysuch.wwyt.bp.service.BpRegulationDocumentTypeService;
import com.joysuch.wwyt.core.bean.BaseAttachmentBean;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.common.util.SimpleDateFormatCache;
import com.joysuch.wwyt.core.entity.BaseAttachmentRepo;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.repository.BaseAttachmentRepoDao;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.joysuch.wwyt.core.support.Context;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

@Service
@Transactional
public class BpRegulationDocumentServiceImpl implements BpRegulationDocumentService {

    @Autowired
    private BpRegulationDocumentDao dao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;

    @Autowired
    private BpRegulationDocumentTypeService bpRegulationDocumentTypeService;

    @Autowired
    private BaseUserDao baseUserDao;

    @Autowired
    private BaseAttachmentRepoDao attachmentRepositoryDao;

    @Value("${wwyt.base.serverUrl}")
    private String serverUrl;

    @Override
    public void add(BpRegulationDocumentAddBean regDocAdd) throws Exception {
        BpRegulationDocument bpRegulationDocument = new BpRegulationDocument();
        bpRegulationDocument.setName(regDocAdd.getDocName());
        bpRegulationDocument.setDocumentTypeId(regDocAdd.getDocumentTypeId());
        bpRegulationDocument.setMakeUserId(regDocAdd.getMakeUserId());
        bpRegulationDocument.setState(RegulationDocumentTypes.TO_BE_AUDITED.getId());
        bpRegulationDocument.setContent(regDocAdd.getContent());
        bpRegulationDocument.setAttachmentId(regDocAdd.getAttachmentId());
        bpRegulationDocument.setMakeTime(regDocAdd.getMakeTime());
        bpRegulationDocument.setRemark(regDocAdd.getRemark());
        // bpRegulationDocument.setAuditUserId(regDocAdd.getAuditUserId());
        // bpRegulationDocument.setAuditTime(regDocAdd.getAuditTime());
        // bpRegulationDocument.setAuditRemark(regDocAdd.getAuditRemark());
        dao.save(bpRegulationDocument);
        // 更新文档对应类型的文档数量
        bpRegulationDocumentTypeService.documentCountOption(bpRegulationDocument.getDocumentTypeId(), true);
    }

    @Override
    public void update(BpRegulationDocumentEditBean regDocEdit) throws Exception {
        BpRegulationDocument content = dao.findById(regDocEdit.getDocId()).get();
        Long oldTypeId = content.getDocumentTypeId();
        Long newTypeId = regDocEdit.getDocumentTypeId();
        content.setName(regDocEdit.getDocName());

        content.setDocumentTypeId(regDocEdit.getDocumentTypeId());
        content.setMakeUserId(regDocEdit.getMakeUserId());
        // 重置状态为待申请
        content.setState(RegulationDocumentTypes.TO_BE_AUDITED.getId());
        content.setContent(regDocEdit.getContent());
        // 附件 ID 不为空，则更新附件 ID
        if (regDocEdit.getAttachmentId() != null) {
            content.setAttachmentId(regDocEdit.getAttachmentId());
        }
        content.setMakeTime(regDocEdit.getMakeTime());
        content.setRemark(regDocEdit.getRemark());
        // 重置审核相关参数
        content.setAuditUserId(null);
        content.setAuditTime(null);
        content.setAuditRemark(null);
        dao.save(content);

        if (!Objects.equals(oldTypeId, newTypeId)) {
            updateTypeDocumentCount(oldTypeId);
            updateTypeDocumentCount(newTypeId);
        }
    }

    private void updateTypeDocumentCount(Long typeId) {
        if (typeId != null) {
            bpRegulationDocumentTypeService.updateTypeDocumentCount(typeId);
        }
    }

    @Override
    public Page<BpRegulationDocumentListBean> findByPage(Pageable page,
            BpRegulationDocumentListSearchBean regDocListSearch) {
        QBpRegulationDocument qRegDoc = QBpRegulationDocument.bpRegulationDocument;
        Predicate predicate = qRegDoc.isNotNull();
        predicate = regDocListSearch.getName() == null ? predicate
                : ExpressionUtils.and(predicate, qRegDoc.name.like("%" + regDocListSearch.getName() + "%"));
        // typeId null ---> get all types that belongs to its docCode
        if(regDocListSearch.getDocumentTypeId() == null){
            List<Long> typeIds = bpRegulationDocumentTypeService.getTypeIdByDocCode(regDocListSearch.getDocCode());
            predicate =  ExpressionUtils.and(predicate, qRegDoc.documentTypeId.in(typeIds));
        }else{
            predicate =  ExpressionUtils.and(predicate, qRegDoc.documentTypeId.eq(regDocListSearch.getDocumentTypeId()));
        }


        if (regDocListSearch.getState() != null) {
            String stateStr = regDocListSearch.getState();
            if (stateStr.equals("docAudit")) { // 文档审核：[等待审核、审核不通过]
                BooleanExpression in = qRegDoc.state.in(RegulationDocumentTypes.AUDIT_WAIT.getId(),
                        RegulationDocumentTypes.AUDIT_FAILED.getId());
                predicate = predicate == null ? in : ExpressionUtils.and(predicate, in);
            } else if (stateStr.equals("docArchive")) { // 文档归档：[审核通过]
                BooleanExpression eq = qRegDoc.state.eq(RegulationDocumentTypes.AUDIT_PASS.getId());
                predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
            }
        }
        page = PageDataUtils.addOrderByDesc(page, "id");
        Page<BpRegulationDocument> all = dao.findAll(predicate, page);
        return convertPageData(all);
    }

    @Override
    public void delete(Long id) {
        BpRegulationDocument content = dao.findById(id).get();
        dao.deleteById(id);
        // 更新文档对应类型的文档数量
        bpRegulationDocumentTypeService.documentCountOption(content.getDocumentTypeId(), false);
    }

    @Override
    public BpRegulationDocument findById(Long id) {
        return dao.findById(id).get();
    }

    @Override
    public void changeState(Long id, Boolean isPass, String auditRemark) {
        BpRegulationDocument content = dao.findById(id).get();
        if (content != null) {
            if (content.getState() == RegulationDocumentTypes.TO_BE_AUDITED.getId()) {
                // 如果是待申请，则更新成等待审核
                content.setState(RegulationDocumentTypes.AUDIT_WAIT.getId());
            } else if (content.getState() == RegulationDocumentTypes.AUDIT_WAIT.getId()) {
                // 如果是等待审核，根据 isPass 更新
                if (isPass) { // 更新成审核通过
                    content.setAuditUserId(Context.getCurrentUserId());
                    content.setAuditRemark(auditRemark);
                    content.setAuditTime(new Date());
                    content.setState(RegulationDocumentTypes.AUDIT_PASS.getId());
                } else { // 更新成审核不通过
                    content.setAuditUserId(Context.getCurrentUserId());
                    content.setAuditRemark(auditRemark);
                    content.setAuditTime(new Date());
                    content.setState(RegulationDocumentTypes.AUDIT_FAILED.getId());
                }
            } else {
                // 其他状态，不进行更改
                return;
            }
            dao.save(content);
        }
    }

    private Page<BpRegulationDocumentListBean> convertPageData(Page<BpRegulationDocument> sourceData) {
        return PageDataUtils.convertPageData(sourceData,
                new PageDataUtils.PageDataConvert<BpRegulationDocumentListBean, BpRegulationDocument>() {

                    @Override
                    public BpRegulationDocumentListBean convert(BpRegulationDocument brd) {
                        BpRegulationDocumentListBean bean = new BpRegulationDocumentListBean();
                        bean.setId(brd.getId());
                        bean.setName(brd.getName());
                        // 文档 ID
                        bean.setDocumentTypeId(brd.getDocumentTypeId());
                        // 文档类型名称
                        bean.setDocumentTypeName(
                                bpRegulationDocumentTypeService.findById(brd.getDocumentTypeId()).getName());
                        // 制定人 ID
                        bean.setMakeUserId(brd.getMakeUserId());
                        // 制定人名称
                        bean.setMakeUserName(baseUserDao.getBaseUserNameById(brd.getMakeUserId()));
                        // 制定时间
                        // 状态 ID
                        bean.setState(brd.getState());
                        // 状态名称
                        bean.setStateName(RegulationDocumentTypes.findByID(brd.getState()).getName());
                        // 内容
                        bean.setContent(brd.getContent());
                        // 附件对象 [附件 ID 、附件名称、下载地址]
                        if (brd.getAttachmentId() != null) {
                            BaseAttachmentRepo baseAttachmentRepo = attachmentRepositoryDao
                                    .findById(brd.getAttachmentId()).get();
                            BaseAttachmentBean baseAttachmentBean = new BaseAttachmentBean();
                            baseAttachmentBean.setId(baseAttachmentRepo.getId());
                            baseAttachmentBean.setName(baseAttachmentRepo.getFileName());
                            baseAttachmentBean
                                    .setDownloadUrl(serverUrl + "/file/download?id=" + baseAttachmentRepo.getId());
                            bean.setBaseAttachmentBean(baseAttachmentBean);
                        }
                        if (brd.getMakeTime() != null) {
                            bean.setMakeTime(SimpleDateFormatCache.getYmdhms().format(brd.getMakeTime()));
                        }
                        // 备注
                        bean.setRemark(brd.getRemark());
                        if (brd.getAuditUserId() != null) {
                            bean.setAuditUserId(brd.getAuditUserId());
                            BaseUser baseUser = baseUserDao.findById(brd.getAuditUserId()).get();
                            bean.setAuditUserName(baseUser.getRealName());
                        }
                        if (brd.getAuditTime() != null) {
                            bean.setAuditTime(SimpleDateFormatCache.getYmdhms().format(brd.getMakeTime()));
                        }
                        bean.setAuditRemark(brd.getAuditRemark());
                        return bean;
                    }
                });
    }

}
